for await ... of {javascript}
for await...of
is a special kind of loop in JavaScript used to asynchronously iterate over data sources that conform to the async iterable protocol, such as:
- Async generators
- Streams
- Asynchronous iterables like
ReadableStream
or paginated APIs
✅ Syntax
for await (const item of asyncIterable) {
// use item
}
This loop:
- Awaits the resolution of each item before moving to the next
- Does not run all iterations in parallel (unlike
Promise.all
)
🧠 When to Use
Use for await...of
when:
- You are consuming a stream or sequence of async events
- Each iteration depends on the previous one finishing
- You want to process large datasets one chunk at a time (e.g., files, network responses)
📦 Example 1: Async Generator
async function* generateNumbers() {
for (let i = 0; i < 3; i++) {
await new Promise(res => setTimeout(res, 1000)); // Simulate delay
yield i;
}
}
(async () => {
for await (const num of generateNumbers()) {
console.log(num); // Prints 0, 1, 2 (1 per second)
}
})();
📦 Example 2: Reading from a File Stream (Node.js)
import fs from 'fs';
const stream = fs.createReadStream('./bigfile.txt', { encoding: 'utf8' });
for await (const chunk of stream) {
console.log('Received chunk:', chunk);
}
🧱 Under the Hood
for await...of
looks for a method[Symbol.asyncIterator]()
on the object- It expects an object with
next()
returning{ value, done }
wrapped in aPromise
⚠️ Gotchas
- Cannot be used in non-async functions
- If the iterable is not async (e.g., just an array), it will throw unless coerced
- All iterations run sequentially, not concurrently
Would you like a comparison between for await...of
and Promise.all
for batching or parallelism?